package dao

import (
	"go-admin1/admin/system/model"
	"go-admin1/internal/infrastructure/database"
	"go-admin1/internal/infrastructure/logger"

	"go.uber.org/zap"
	"gorm.io/gorm"
)

// UserRepository 用户仓储接口
type UserRepository interface {
	Create(user *model.User) error
	GetByID(id uint64) (*model.User, error)
	GetByUsername(username string) (*model.User, error)
	Update(user *model.User) error
	Delete(id uint64) error
	List(page, pageSize int) ([]*model.User, int64, error)
}

type userRepository struct {
	db *gorm.DB
}

// NewUserRepository 创建用户仓储实例
func NewUserRepository() UserRepository {
	return &userRepository{
		db: database.GetDB(),
	}
}

func (r *userRepository) Create(user *model.User) error {
	logger.Info("创建用户", zap.Uint64("user_id", user.ID))
	return r.db.Create(user).Error
}

func (r *userRepository) GetByID(id uint64) (*model.User, error) {
	logger.Debug("根据ID获取用户", zap.Uint64("user_id", id))
	var user model.User
	err := r.db.Where("user_id = ?", id).First(&user).Error
	return &user, err
}

func (r *userRepository) GetByUsername(username string) (*model.User, error) {
	logger.Debug("根据用户名获取用户", zap.String("user_name", username))
	var user model.User
	err := r.db.Where("user_name = ? ", username).First(&user).Error
	return &user, err
}

func (r *userRepository) Update(user *model.User) error {
	logger.Info("更新用户", zap.Uint64("user_id", user.ID))
	return r.db.Save(user).Error
}

func (r *userRepository) Delete(id uint64) error {
	logger.Info("删除用户", zap.Uint64("user_id", id))
	return r.db.Where("id = ?", id).Delete(&model.User{}).Error
}

func (r *userRepository) List(page, pageSize int) ([]*model.User, int64, error) {
	logger.Debug("获取用户列表", zap.Int("page", page), zap.Int("page_size", pageSize))
	var users []*model.User
	var total int64

	offset := (page - 1) * pageSize
	db := r.db.Model(&model.User{}).Where("del_flag =0")

	if err := db.Count(&total).Error; err != nil {
		return nil, 0, err
	}

	if err := db.Offset(offset).Limit(pageSize).Find(&users).Error; err != nil {
		return nil, 0, err
	}

	return users, total, nil
}
